/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.freedoit.gui;

import com.google.gson.Gson;
import java.awt.AWTEvent;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import org.freedoit.FreeDoitConfig;
import org.freedoit.common.data.FreeDoitTaskRequest;
import org.freedoit.common.data.FreeDoitTaskResponse;
import org.freedoit.common.util.FreeDoitDataUtils;
import org.freedoit.common.util.SharedConstants;
import org.freedoit.dao.DAOFactory;
import org.freedoit.om.Task;
import org.freedoit.util.Constants;
import org.freedoit.util.SyncService;
import org.freedoit.util.SyncServiceCallBack;
import org.freedoit.util.Utils;

/**
 *
 * @author wanglei
 */
public class DoitFrame extends javax.swing.JFrame {

    /**
     * Creates new form DoitFrame
     */
    private class JLabelSyncServiceCallBack implements SyncServiceCallBack {

        public void before() {
            jLabelSyncStatus.setText(FreeDoitConfig.getText("frame.doit.label.synchronizing"));
            jButtonSync.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/synchronizing_16.gif")));
        }

        public void after(boolean isOK) {
            StringBuilder sbMsg = new StringBuilder();
            sbMsg.append(FreeDoitConfig.getText("frame.doit.label.last.synchronized.at"));
            sbMsg.append(Constants.dateTimeFullSdf.format(new java.util.Date()));
            if (!isOK) {
                sbMsg.append(FreeDoitConfig.getText("frame.doit.label.last.synchronized.failed"));
            }
            jLabelSyncStatus.setText(sbMsg.toString());
            jButtonSync.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/synchronize_16.png")));
        }
        
    };
    public DoitFrame() {
        initComponents();
        defaultSetting();
    }
    
    protected void processWindowEvent(WindowEvent e) {  
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            this.setVisible(false);
            return; //return to prevent close
        }
        super.processWindowEvent(e); //other event  
    }
    
    private void addTaskIntoList(Task task, int index) {
            DefaultListModel dlm = (DefaultListModel)(this.jListTaskList.getModel());
            dlm.addElement(new TaskItemPanel(task));
            
            Object actionItem = this.jListActionList.getModel().getElementAt(index);
            if (actionItem instanceof ActionPanel) {
                ActionPanel actionPanel = (ActionPanel)actionItem;
                actionPanel.addTaskCount(new Integer(1));
            }
    }
    
    private void removeTaskFromList(int taskIndex, int actionIndex) {
            DefaultListModel dlm = (DefaultListModel)(this.jListTaskList.getModel());
            dlm.removeElementAt(taskIndex);
            
            Object actionItem = this.jListActionList.getModel().getElementAt(actionIndex);
            if (actionItem instanceof ActionPanel) {
                ActionPanel actionPanel = (ActionPanel)actionItem;
                actionPanel.addTaskCount(new Integer(-1));
            }
    }
    
    private void defaultSetting() {
        // enable processing window event
        this.enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        
        this.setIconImage(Toolkit.getDefaultToolkit().getImage(""));//remove icon
        
        TaskItemRenderer listHelper = new TaskItemRenderer(this);
        this.jListTaskList.addMouseListener(listHelper);
        this.jListTaskList.setCellRenderer(listHelper);
        
        this.jListActionList.setBackground(this.jPanelAction.getBackground());
        
        ActionItemRenderer actionListRenderer = new ActionItemRenderer();
        DefaultListModel dlm = new DefaultListModel();
        dlm.addElement(new ActionPanel("/icon/idea_16.png", 
                FreeDoitConfig.getText("frame.doit.list.text.idea"), null));
        dlm.addElement(new ActionPanel("/icon/today_16.png", 
                FreeDoitConfig.getText("frame.doit.list.text.today"), null));
        dlm.addElement(new ActionPanel("/icon/tomorrow_16.png", 
                FreeDoitConfig.getText("frame.doit.list.text.tomorrow"), null));
        dlm.addElement(new ActionPanel("/icon/future_16.png", 
                FreeDoitConfig.getText("frame.doit.list.text.future"), null));
        dlm.addElement(new ActionPanel("/icon/finished_16.png", 
                FreeDoitConfig.getText("frame.doit.list.text.finished"), null));
        this.jListActionList.setModel(dlm);
        this.jListActionList.setCellRenderer(actionListRenderer);
        this.jListActionList.setSelectedIndex(INDEX_TODAY);
        loadTaskList(INDEX_TODAY);
        
        // Start a timer to auto update 
        long lSyncFreq = FreeDoitConfig.getSyncFreq();
        if (lSyncFreq > 0) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                public void run() {
                    // If new task updated from remote, update the view
                    if (SyncService.execSendReceiveService(new JLabelSyncServiceCallBack()) > 0) {
                        loadTaskList(jListActionList.getSelectedIndex());
                    }
                }

            }, 0, lSyncFreq);
        }
        //loadTaskListOfToday();
        Utils.displayAtCentralScreen(this);
    }
    
    private static int INDEX_COLLECT = 0;
    private static int INDEX_TODAY = 1;
    private static int INDEX_TOMORROW = 2;
    private static int INDEX_FUTURE = 3;
    private static int INDEX_FINISHED = 4;

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelTop = new javax.swing.JPanel();
        tipTextFiledAddTaskQuickly = new org.freedoit.gui.TipTextFiled(FreeDoitConfig.getText("frame.doit.add.task.quickly"));
        jPanelTaskList = new javax.swing.JPanel();
        jListTaskList = new javax.swing.JList();
        jPanelBox = new javax.swing.JPanel();
        jListActionList = new javax.swing.JList();
        jPanelStatus = new javax.swing.JPanel();
        jLabelSyncStatus = new javax.swing.JLabel();
        jButtonSync = new javax.swing.JButton();
        jPanelAction = new javax.swing.JPanel();
        jButtonNewTask = new javax.swing.JButton();
        jButtonEditTask = new javax.swing.JButton();
        jButtonDeleteTask = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(218, 218, 242));
        setFont(FreeDoitConfig.getFont(0, 11));
        setIconImages(null);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        jPanelTop.setBackground(new java.awt.Color(218, 218, 242));
        jPanelTop.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

        tipTextFiledAddTaskQuickly.setFont(FreeDoitConfig.getFont(0, 12));
        tipTextFiledAddTaskQuickly.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                tipTextFiledAddTaskQuicklyActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelTopLayout = new javax.swing.GroupLayout(jPanelTop);
        jPanelTop.setLayout(jPanelTopLayout);
        jPanelTopLayout.setHorizontalGroup(
            jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelTopLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tipTextFiledAddTaskQuickly, javax.swing.GroupLayout.PREFERRED_SIZE, 520, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanelTopLayout.setVerticalGroup(
            jPanelTopLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelTopLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tipTextFiledAddTaskQuickly, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelTaskList.setBackground(new java.awt.Color(255, 255, 255));
        jPanelTaskList.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

        jListTaskList.setBackground(new java.awt.Color(254, 254, 254));
        jListTaskList.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jListTaskList.setFixedCellHeight(30);
        jListTaskList.setSelectionBackground(new java.awt.Color(153, 255, 255));
        jListTaskList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jListTaskListMouseClicked(evt);
            }
        });
        jListTaskList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListTaskListValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanelTaskListLayout = new javax.swing.GroupLayout(jPanelTaskList);
        jPanelTaskList.setLayout(jPanelTaskListLayout);
        jPanelTaskListLayout.setHorizontalGroup(
            jPanelTaskListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelTaskListLayout.createSequentialGroup()
                .addComponent(jListTaskList, javax.swing.GroupLayout.PREFERRED_SIZE, 706, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
        );
        jPanelTaskListLayout.setVerticalGroup(
            jPanelTaskListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelTaskListLayout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(jListTaskList, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jPanelBox.setBackground(new java.awt.Color(218, 218, 242));
        jPanelBox.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));
        jPanelBox.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        jListActionList.setBackground(Utils.getComponentColor("Panel.background"));
        jListActionList.setFont(FreeDoitConfig.getFont(0, 14));
        jListActionList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "    Collector", "    Today", "    Tomorrow", "    Future", "    Finished" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jListActionList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        jListActionList.setFixedCellHeight(25);
        jListActionList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jListActionListMouseClicked(evt);
            }
        });
        jListActionList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListActionListValueChanged(evt);
            }
        });

        javax.swing.GroupLayout jPanelBoxLayout = new javax.swing.GroupLayout(jPanelBox);
        jPanelBox.setLayout(jPanelBoxLayout);
        jPanelBoxLayout.setHorizontalGroup(
            jPanelBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jListActionList, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
        );
        jPanelBoxLayout.setVerticalGroup(
            jPanelBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelBoxLayout.createSequentialGroup()
                .addGap(103, 103, 103)
                .addComponent(jListActionList)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelStatus.setBackground(new java.awt.Color(204, 204, 204));
        jPanelStatus.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

        jLabelSyncStatus.setBackground(new java.awt.Color(204, 204, 204));
        jLabelSyncStatus.setFont(FreeDoitConfig.getFont(0, 12));
        jLabelSyncStatus.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);

        jButtonSync.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/synchronize_16.png"))); // NOI18N
        jButtonSync.setBorder(null);
        jButtonSync.setBorderPainted(false);
        jButtonSync.setContentAreaFilled(false);
        jButtonSync.setIconTextGap(0);
        jButtonSync.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonSync.setMaximumSize(new java.awt.Dimension(16, 16));
        jButtonSync.setMinimumSize(new java.awt.Dimension(16, 16));
        jButtonSync.setPreferredSize(new java.awt.Dimension(16, 16));
        jButtonSync.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSyncActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelStatusLayout = new javax.swing.GroupLayout(jPanelStatus);
        jPanelStatus.setLayout(jPanelStatusLayout);
        jPanelStatusLayout.setHorizontalGroup(
            jPanelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelStatusLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButtonSync, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabelSyncStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 452, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanelStatusLayout.setVerticalGroup(
            jPanelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabelSyncStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jButtonSync, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)
        );

        jPanelAction.setBackground(new java.awt.Color(218, 218, 242));
        jPanelAction.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

        jButtonNewTask.setBackground(jPanelAction.getBackground());
        jButtonNewTask.setFont(FreeDoitConfig.getFont(0, 12));
        jButtonNewTask.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/plus_24.png"))); // NOI18N
        jButtonNewTask.setText(FreeDoitConfig.getText("frame.doit.button.new"));
        jButtonNewTask.setToolTipText(FreeDoitConfig.getText("frame.doit.button.tooltip.new"));
        jButtonNewTask.setBorder(null);
        jButtonNewTask.setBorderPainted(false);
        jButtonNewTask.setContentAreaFilled(false);
        jButtonNewTask.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonNewTask.setIconTextGap(2);
        jButtonNewTask.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonNewTask.setMaximumSize(new java.awt.Dimension(45, 45));
        jButtonNewTask.setMinimumSize(new java.awt.Dimension(45, 45));
        jButtonNewTask.setPreferredSize(new java.awt.Dimension(45, 45));
        jButtonNewTask.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonNewTask.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonNewTaskActionPerformed(evt);
            }
        });

        jButtonEditTask.setBackground(jPanelAction.getBackground());
        jButtonEditTask.setFont(FreeDoitConfig.getFont(0, 12));
        jButtonEditTask.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/edit_24.png"))); // NOI18N
        jButtonEditTask.setText(FreeDoitConfig.getText("frame.doit.button.edit"));
        jButtonEditTask.setToolTipText(FreeDoitConfig.getText("frame.doit.button.tooltip.edit"));
        jButtonEditTask.setBorder(null);
        jButtonEditTask.setBorderPainted(false);
        jButtonEditTask.setContentAreaFilled(false);
        jButtonEditTask.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonEditTask.setIconTextGap(2);
        jButtonEditTask.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonEditTask.setMaximumSize(new java.awt.Dimension(45, 45));
        jButtonEditTask.setMinimumSize(new java.awt.Dimension(45, 45));
        jButtonEditTask.setPreferredSize(new java.awt.Dimension(45, 45));
        jButtonEditTask.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonEditTask.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonEditTaskActionPerformed(evt);
            }
        });

        jButtonDeleteTask.setBackground(jPanelAction.getBackground());
        jButtonDeleteTask.setFont(FreeDoitConfig.getFont(0, 12));
        jButtonDeleteTask.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icon/delete_24.png"))); // NOI18N
        jButtonDeleteTask.setText(FreeDoitConfig.getText("frame.doit.button.delete"));
        jButtonDeleteTask.setToolTipText(FreeDoitConfig.getText("frame.doit.button.tooltip.delete"));
        jButtonDeleteTask.setBorder(null);
        jButtonDeleteTask.setBorderPainted(false);
        jButtonDeleteTask.setContentAreaFilled(false);
        jButtonDeleteTask.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonDeleteTask.setIconTextGap(2);
        jButtonDeleteTask.setMargin(new java.awt.Insets(0, 0, 0, 0));
        jButtonDeleteTask.setMaximumSize(new java.awt.Dimension(45, 45));
        jButtonDeleteTask.setMinimumSize(new java.awt.Dimension(45, 45));
        jButtonDeleteTask.setPreferredSize(new java.awt.Dimension(45, 45));
        jButtonDeleteTask.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonDeleteTask.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonDeleteTaskActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelActionLayout = new javax.swing.GroupLayout(jPanelAction);
        jPanelAction.setLayout(jPanelActionLayout);
        jPanelActionLayout.setHorizontalGroup(
            jPanelActionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelActionLayout.createSequentialGroup()
                .addGap(32, 32, 32)
                .addComponent(jButtonNewTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(84, 84, 84)
                .addComponent(jButtonEditTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(75, 75, 75)
                .addComponent(jButtonDeleteTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanelActionLayout.setVerticalGroup(
            jPanelActionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelActionLayout.createSequentialGroup()
                .addGap(0, 8, Short.MAX_VALUE)
                .addGroup(jPanelActionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonNewTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonEditTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonDeleteTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(jPanelTaskList, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jPanelAction, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jPanelTop, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(jPanelBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanelTop, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGap(0, 0, 0)
                        .addComponent(jPanelTaskList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, 0)
                        .addComponent(jPanelAction, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jPanelBox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(0, 0, 0)
                .addComponent(jPanelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void loadTaskList(int index) {
        boolean blnNotFinishIndex = true;
        if (index == INDEX_COLLECT) {
            loadTaskList(index, DAOFactory.getTaskDAO().getTaskListOfCollector());
        } else if (index == INDEX_TODAY) {
            loadTaskList(index, DAOFactory.getTaskDAO().getTaskListOfToday());
        } else if (index == INDEX_TOMORROW) {
            loadTaskList(index, DAOFactory.getTaskDAO().getTaskListOfTomorrow());
        } else if (index == INDEX_FUTURE) {
            loadTaskList(index, DAOFactory.getTaskDAO().getTaskListOfFuture());
        } else if (index == INDEX_FINISHED) {
            loadTaskList(index, DAOFactory.getTaskDAO().getTaskListOfFinished());
            blnNotFinishIndex = false;
        } else {
            // Do nothing
        }

        this.jButtonNewTask.setEnabled(blnNotFinishIndex);
        this.tipTextFiledAddTaskQuickly.setEnabled(blnNotFinishIndex);
        
        this.jButtonEditTask.setEnabled(false);
        this.jButtonDeleteTask.setEnabled(false);
    }
    private void jListActionListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListActionListValueChanged
        // TODO add your handling code here:
        //System.out.println("Action");
    }//GEN-LAST:event_jListActionListValueChanged

    private void jListTaskListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListTaskListValueChanged
        // TODO add your handling code here:
        Object source = evt.getSource();
        if (source instanceof JList) {
            JList list = (JList)source;
            
            if (this.jListActionList.getSelectedIndex() != INDEX_FINISHED) {
                boolean hasTaskSelected = (list.getSelectedIndex() != -1);
                this.jButtonEditTask.setEnabled(hasTaskSelected);
                this.jButtonDeleteTask.setEnabled(hasTaskSelected);
            }
        }
    }//GEN-LAST:event_jListTaskListValueChanged

    void remoteSyncTask(final Task task, final String remoteService) {
        if (task.getSerialNo() == null) { // new Task
            DAOFactory.getTaskDAO().persist(task);
        } else {
            DAOFactory.getTaskDAO().update(task);
        }
        
        final SyncServiceCallBack callback = new JLabelSyncServiceCallBack();
        new Thread (new Runnable () {

            public void run() {
                // prepare json request data
                Gson retGson = FreeDoitDataUtils.createStandardJson();
                FreeDoitTaskRequest fdtr = new FreeDoitTaskRequest();
                fdtr.setTask(Utils.toSharedData(task));
                String message = retGson.toJson(fdtr,  new com.google.gson.reflect.TypeToken<FreeDoitTaskRequest>() {  
                            }.getType());
                
                System.out.println(message);

                callback.before();
                String responseBody = Utils.sendHttpPostMessage(message, remoteService);

                // parse response
                if (responseBody == null) {
                    callback.after(false);
                } else {
                    System.out.println(responseBody);
                    FreeDoitTaskResponse result = retGson.fromJson(responseBody, 
                            new com.google.gson.reflect.TypeToken<FreeDoitTaskResponse>() {  
                                }.getType());

                    if (result.getCode() == FreeDoitTaskResponse.CODE_OK) {
                        System.out.println(result.getTaskID());
                        callback.after(true);
                        

                        // Update local task object
                        if (task.getTaskId() == null) {
                            task.setTaskId(result.getTaskID());
                        }
                        task.setLastModifyTime(result.getTimestamp());

                        if (!task.getSynced()) {
                            task.setSynced(true);
                        }
                        
                        System.out.println("Serial No:" + task.getSerialNo());
                        DAOFactory.getTaskDAO().update(task);
                    } else {
                        callback.after(false);
                    }
                }
            }

        }).start();
    }
    
    public boolean isDialogPopup() {
        return this.blnDialogPopup;
    }
    private boolean doTask(final Task task, final String remoteService, int x, int y) {
        this.blnDialogPopup = true;
        TaskDialog td = new TaskDialog(task, this);
        td.setLocation(x, y);
        td.setVisible(true);
        this.blnDialogPopup = false;
        
        if (td.isOKClicked()) {
            // remote sync
            remoteSyncTask(task, remoteService);
            return true;
        } else {
            return false;
        }
        
    }
    private void jButtonNewTaskActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonNewTaskActionPerformed
        // TODO add your handling code here:
        int index = this.jListActionList.getSelectedIndex();
        Task task = createNewTask(null, index);
        java.sql.Date date = task.getStartDate();
        
        Point p = this.jListTaskList.getLocationOnScreen();
        if (!doTask(task, FreeDoitConfig.ADD_TASK_SERVICE, p.x, p.y)) {
            return;
        }
        
        // refresh
        if (date != null) {
            if (index == INDEX_TODAY) {
                // if it is task needed to be display under "Today"
                // insert into list
                if (date.compareTo(task.getStartDate()) <= 0) {
                    addTaskIntoList(task, index);
                }
            } else {
                // If it is start date equals the date of current display
                // insert into list
                if (date.compareTo(task.getStartDate()) == 0) {
                    addTaskIntoList(task, index);
                }
            }
        } else {
            // no start date, collector
            // And task has no start date, insert into the list
            if (task.getStartDate() == null) {
                    addTaskIntoList(task, index);
            }
        }
    }//GEN-LAST:event_jButtonNewTaskActionPerformed

    private void editSelectedTask() {
        int iSelIndex = this.jListTaskList.getSelectedIndex();
        Object obj = this.jListTaskList.getSelectedValue();
        if (obj instanceof TaskItemPanel) {
            Task task = ((TaskItemPanel)obj).getTask();
            Point p = this.jListTaskList.getLocationOnScreen();
            if (!doTask(task, FreeDoitConfig.UPDATE_TASK_SERVICE, p.x, p.y)) {
                return;
            }
        
            // refresh
            int index = this.jListActionList.getSelectedIndex();
            if (index == INDEX_TODAY) {
                // if it is task needed to be display under "Today"
                // only refresh the item, otherwise remove it
                if (task.getStartDate() == null || 
                        Utils.compareSQLDate(Utils.getToday(), task.getStartDate()) < 0) {
                    removeTaskFromList(iSelIndex, index);
                }
                jListTaskList.repaint();
            } else if (index == INDEX_TOMORROW) {
                // If it is start date equals the date of current display
                // only refresh the item, otherwise remove it
                if (task.getStartDate() == null || 
                        Utils.isSameSQLDate(Utils.getTomorrow(), task.getStartDate())) {
                    removeTaskFromList(iSelIndex, index);
                }
                jListTaskList.repaint();
            } else if (index == INDEX_FUTURE) {
                // If it is start date equals the date of current display
                // only refresh the item, otherwise remove it
                if (task.getStartDate() == null || 
                        Utils.compareSQLDate(Utils.getTheDayAfterTomorrow(), task.getStartDate()) > 0) {
                    removeTaskFromList(iSelIndex, index);
                }
                jListTaskList.repaint();
            } else if (index == INDEX_COLLECT) {
                // If it is start date equals the date of current display
                // only refresh the item, otherwise remove it
                if (task.getStartDate() != null) {
                    removeTaskFromList(iSelIndex, index);
                }
                jListTaskList.repaint();
            } else {
                // Do nothing
            }
        }
        
    }
    private void jButtonEditTaskActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEditTaskActionPerformed
        // TODO add your handling code here:
        editSelectedTask();
    }//GEN-LAST:event_jButtonEditTaskActionPerformed

    private void jButtonDeleteTaskActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeleteTaskActionPerformed
        // TODO add your handling code here:
        Object obj = this.jListTaskList.getSelectedValue();
        if (obj instanceof TaskItemPanel) {
            Task task = ((TaskItemPanel)obj).getTask();
            task.setStatus(SharedConstants.DELETED_INTEGER);
            if (task.getTaskId() == null) {
                remoteSyncTask(task, FreeDoitConfig.ADD_TASK_SERVICE);
            } else {
                remoteSyncTask(task, FreeDoitConfig.DELETE_TASK_SERVICE);
            }
            
            // update gui
            removeTaskFromList(jListTaskList.getSelectedIndex(), this.jListActionList.getSelectedIndex());
            jListTaskList.repaint();
        }
    }//GEN-LAST:event_jButtonDeleteTaskActionPerformed

    public void performSync() {
        final JLabelSyncServiceCallBack callback = new JLabelSyncServiceCallBack();
        callback.before();
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                if (SyncService.execSendReceiveService(callback) > 0) {
                    loadTaskList(jListActionList.getSelectedIndex());
                }
            }
        });
    }
    private void jButtonSyncActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSyncActionPerformed
        // TODO add your handling code here:
        performSync();
    }//GEN-LAST:event_jButtonSyncActionPerformed

    private static Task createNewTask(String taskName, int dateIndex) {
        Task task = new Task();
        int index = dateIndex;
        java.sql.Date date = null;
        if (index == INDEX_TODAY) {
            date = Utils.getToday();
            task.setStartDate(date);
            //task.setStartTime(Utils.getNextTimePointFromNow());
        } else if (index == INDEX_TOMORROW) {
            date = Utils.getTomorrow();
            task.setStartDate(date);
        } else if (index == INDEX_FUTURE) {
            date = Utils.getTheDayAfterTomorrow();
            task.setStartDate(date);
        } else {
            // Do nothing
        }
        
        task.setStatus(SharedConstants.ACTIVE_INTEGER);
        
        // Set Name if provided
        if (taskName != null && !"".equals(taskName)) {
            task.setTaskName(taskName);
        }
        return task;
        
    }
    private void tipTextFiledAddTaskQuicklyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tipTextFiledAddTaskQuicklyActionPerformed
        // TODO add your handling code here:
        String taskName = this.tipTextFiledAddTaskQuickly.getText();
        if (taskName != null && !"".equals(taskName)) {
            // Create Task Object
            Task newTask = createNewTask(taskName, this.jListActionList.getSelectedIndex());
        
            // Synchronization
            remoteSyncTask(newTask, FreeDoitConfig.ADD_TASK_SERVICE);
            
            // Update Task List
            addTaskIntoList(newTask, this.jListActionList.getSelectedIndex());
            
            // Clear the existing Text
            this.tipTextFiledAddTaskQuickly.setText("");
        }
        
        // remove focus
        this.tipTextFiledAddTaskQuickly.setFocusable(false);
    }//GEN-LAST:event_tipTextFiledAddTaskQuicklyActionPerformed

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        // TODO add your handling code here:
        this.jListActionList.requestFocus();
    }//GEN-LAST:event_formWindowOpened

    private void jListActionListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListActionListMouseClicked
        // TODO add your handling code here:
        loadTaskList(((javax.swing.JList)evt.getSource()).getSelectedIndex());
    }//GEN-LAST:event_jListActionListMouseClicked

    private void jListTaskListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListTaskListMouseClicked
        // TODO add your handling code here:
        if (evt.getClickCount() == 2) { // double click
            editSelectedTask();
        }
    }//GEN-LAST:event_jListTaskListMouseClicked

    private void loadTaskList(final int index, final List<Task> taskList) {
//        java.awt.EventQueue.invokeLater(new Runnable() {
//            public void run() {
                DefaultListModel dlm = new DefaultListModel();
                int iLen = 0;
                if (taskList != null && (iLen = taskList.size()) > 0) {
                    for (Task t : taskList) {
                        dlm.addElement(new TaskItemPanel(t));
                    }
                    
                    Object obj = jListActionList.getModel().getElementAt(index);
                    if (obj instanceof ActionPanel) {
                        ((ActionPanel)obj).updateTaskCount(iLen > 0 ? new Integer(iLen) : null);
                    }
                }
                jListTaskList.getSelectionModel().clearSelection();
                jListTaskList.setModel(dlm);
                jListTaskList.repaint();
//            }
//        });
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(DoitFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(DoitFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(DoitFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(DoitFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DoitFrame().setVisible(true);
            }
        });
    }
    private Timer timer;
    private boolean blnDialogPopup;
    //private boolean blnActionListChanged;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonDeleteTask;
    private javax.swing.JButton jButtonEditTask;
    private javax.swing.JButton jButtonNewTask;
    private javax.swing.JButton jButtonSync;
    private javax.swing.JLabel jLabelSyncStatus;
    private javax.swing.JList jListActionList;
    private javax.swing.JList jListTaskList;
    private javax.swing.JPanel jPanelAction;
    private javax.swing.JPanel jPanelBox;
    private javax.swing.JPanel jPanelStatus;
    private javax.swing.JPanel jPanelTaskList;
    private javax.swing.JPanel jPanelTop;
    private org.freedoit.gui.TipTextFiled tipTextFiledAddTaskQuickly;
    // End of variables declaration//GEN-END:variables
}
